package com.boot.mapper;

import com.boot.entity.Address;
import com.boot.entity.Menu;
import com.boot.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

//@Mapper:这是给Spring扫描的 Spring会扫描到生成UserMapper的bean对象
@Mapper
public interface UserMapper {

    //数据库操作无非:新增、修改、查询、删除、分页、批量操作

    /**
     * 这里SQL语句和配置文件中一样的
     * 传递参数也是一样的:
     * Map
     * @Param【如果只有一个参数 不加也可以的 多个参数必须要加了 否则只能用arg0、arg1 param1...】
     * JavaBean
     *
     * @param user
     * @return 返回受影响的行数
     *
     * @SelectKey:用来做主键回填 当执行插入之后 将刚刚插入的id查询到 并且放到user对象中
     * statement:执行查询刚刚插入的数据id 如果是其他的数据库 需要根据数据库来
     * keyProperty:实体类对应的主键id名
     * keyColumn:数据库表主键字段名
     * resultType:返回值类型 因为这里的主键ID是BIGINT 对应的Java类型是Long
     * before:true/false true:在插入之前执行 false:在插入之后执行【这里肯定是插入执行执行查询】
     *
     */
    @Insert("insert t_user(userName,password) values(#{userName},#{password})")
    @SelectKey(statement = "select last_insert_id()",keyProperty = "id",keyColumn = "id",resultType = Long.class,before = false)
    int save(User user);

    //@Results:如果在数据库字段名和类属性名一致 可以不加
    @Select("select id,addTime,userName,password,address_id from t_user")
    @Results(id="baseResultMap",value = {
            @Result(property = "id",column = "id",id = true), //主键需要指定
            @Result(property = "addTime",column = "addTime"),
            @Result(property = "userName",column = "userName"),
            @Result(property = "password",column = "password"),
            //property = "address":User类中的一对一的属性名
            //column = "address_id":将t_user表中查询到的address_id放到子查询中
            //one:一对一查询语句
            //mybatis注解只能使用分步查询 单步查询不好操作:会有N+1的问题
            @Result(property = "address",column = "address_id",javaType = Address.class,one = @One(select = "com.boot.mapper.AddressMapper.getById")),
            @Result(property = "menus",column = "id",javaType = Menu.class,many = @Many(select = "com.boot.mapper.MenuMapper.getByUserId"))
    })
    List<User> list();


    @Select("select id,addTime,userName,password,address_id from t_user where id = #{id}")
    /*@Results({
            @Result(property = "id",column = "id",id = true), //主键需要指定
            @Result(property = "addTime",column = "addTime"),
            @Result(property = "userName",column = "userName"),
            @Result(property = "password",column = "password")
    })*/
    @ResultMap("baseResultMap") //复用结果集
    User getById(Long id);

    //select id,addTime,userName,password from t_user where userName like '%张%'
    //'%${userName}%':字符串拼接
    //#:通过JDBC的 PreparedStatement 占位形式
    //$:通过JDBC的 Statement 字符串拼接 有SQL注入安全问题
    @Select("select id,addTime,userName,password from t_user where userName like '%${userName}%'")
    List<User> getByUserName(@Param("userName") String userName);

}
